#include <gdsl.h>
#include <stdlib.h>
#include <string.h>

#define _END

#define NOT_FOUND -333

#define IND -128
#define FOREACH(type , element,  list , cursor, iterator ) \
	iterator = 0 ; \
	gdsl_list_cursor_t cursor; 		\
	cursor = gdsl_list_cursor_alloc(list);\
	gdsl_list_cursor_move_to_head(cursor);\
	for( element = (type)gdsl_list_get_head(list);\
		iterator < gdsl_list_get_size(list);\
		iterator++, \
		gdsl_list_cursor_step_forward(cursor),\
		element= (type) gdsl_list_cursor_get_content(\
		cursor))


#define LEFT(t)       ( (_gdsl_bstree_t) _gdsl_bintree_get_left ((_gdsl_bintree_t) (t)) )
#define RIGHT(t)      ( (_gdsl_bstree_t) _gdsl_bintree_get_right ((_gdsl_bintree_t) (t)) )
#define PARENT(t)     ( (_gdsl_bstree_t) _gdsl_bintree_get_parent ((_gdsl_bintree_t) (t)) )
#define CONTENT(t)    ( _gdsl_bintree_get_content ((_gdsl_bintree_t) (t)) )


#define IS_LEAF(t)    ( _gdsl_bintree_is_leaf ((_gdsl_bintree_t) t) )
#define IS_EMPTY(t)   ( _gdsl_bintree_is_empty ((_gdsl_bintree_t) t) )

#define INSERTED 1
#define NOT_INSERTED 0


typedef enum  { SUJEITO=12 , OBJETO} _funcao_sintatica;

typedef enum { ELIPSE=22, PRONOME ,SND } _classificacao;

typedef enum { COREFERENCIA=32, MEMBRO_DE , ACOMODACAO} _relacao;

typedef enum { MASCULINO=42, FEMININO } _genero;

typedef enum { SINGULAR=52 , PLURAL} _numero;

typedef enum { AUMENTATIVO=62 , DIMINUTIVO } _grau; 

typedef enum { LEFT=253,  RIGHT=254} _pos;

typedef struct _word{
	char 		 *termo;
	_funcao_sintatica funcao_sintatica;
	_classificacao 	  classificacao;
	void*		  end;
	_relacao	  relacao;
	struct _word 	 *antecedente;

	_genero		  genero;
	_numero		  numero;
	_grau		  grau;

}Word,* word;

typedef struct _segmento{
        int 		id;
        int             parent_id;
        int             is_right;
	int 		is_composto;
        int             is_root;
        int             ordem;
	int 		sv_id;
	char		*nome;
        float           h;
        float           w;
	word		fexp;
	word		fimp;
	gdsl_list_t	lrexp;
	gdsl_list_t	lrimp;
	_gdsl_bintree_t end;
	_gdsl_bintree_t sv;
}SEGMENTO, * Segmento;

typedef _gdsl_bintree_t  End;

typedef gdsl_list_t segmento_t;



Segmento interpretacao_fora_contexto_segmento(segmento_t);

End      interpretacao_em_contexto(End end , Segmento no);

void     end_set_nome(End tree, char* nome);

Segmento create_segmento();

Segmento create_segmento_from_data(int id, int parent,int compst,int root,
                                   int pos,int ordem , word fexp, word fimp,
                                   gdsl_list_t lrexp , gdsl_list_t lrimp);

word     create_word();

word     create_word_from_data(char* termo,
                          char* fs,
                           char* ant,
                           char* end,
                           char* gen,
                           char* num,
                           char* gra,
                           char* rel);

End create_end_from_node_list(gdsl_list_t segmentos);

int   get_segmento_id(_gdsl_bintree_t tree);

Segmento  get_segmento(_gdsl_bintree_t tree);

char* get_segmento_id_str(_gdsl_bintree_t tree);

void set_segmento_end(Segmento s, End tree);

int end_get_height(End tree);

int end_get_size(End tree);

End find_node_by_id(const End e, int s_id) ;

long int _compare_end_nodes_id(const gdsl_element_t E, void * value);

double end_relevance_term(End e, char* term);

int
end_search (const End t, const gdsl_compare_func_t comp_f,
		     const gdsl_element_t v, End * found);

